
package nl.hanze.shoestring.ui;

import com.toedter.components.JSpinField;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.html.HTMLEditorKit;
import nl.hanze.shoestring.domain.Land;
import nl.hanze.shoestring.domain.Reis;
import nl.hanze.shoestring.domain.Reistype;
import nl.hanze.shoestring.logic.Logic;
import nl.hanze.shoestring.logic.Utils;

/**
 *  ReisPanel
 *  ReisPanel is de GUI waarin de Reizen kunnen worden opgevraagd en bewerkt.
 * 
 * @author henk
 */
public class ReisPanel extends JPanel {
    private static final long serialVersionUID = 1L;

    Logic logic;
    JPanel pQueryInput, pRecord, pNavigation, pDbGrid;
    JLabel lblZoekSleutel, lblId, lblLand, lblReistype, lblDuur;
    JLabel lblVerlenging, lblOmschrijving, lblNaam, lblAfbeelding, picLabel;
    JTextField txtZoekSleutel, txtId, txtNaam, txtAfbeelding;
    JButton butZoeken, butSave, butDelete, butEmpty, butRefresh;
    JCheckBox chkVerlenging;
    JComboBox<Object> cmbLand, cmbReistype;
    JSpinField spinDuur;
    JEditorPane txtOmschrijving;
    JTable table;
    JScrollPane scrollPaneRes, txtOmschrijvingScrollable;
    DefaultTableModel model;
    Reis reisObj=null;
    List<Reis> reisList;

    int heightField = 25;
    int numberOfRows = 14;

    public ReisPanel(Logic logic) {
        this.logic = logic;
        
        table = new JTable();
        setLayout(new BorderLayout(20, 20));

        // zoek optie  north sectie
        pQueryInput = new JPanel();
        pQueryInput.setLayout(null);
        pQueryInput.setPreferredSize(new Dimension(400, 40));

        lblZoekSleutel = UIHelper.createLabel(lblZoekSleutel = new JLabel(), "Zoeksleutel", 20, 10, 150, heightField, pQueryInput);
        txtZoekSleutel = UIHelper.createTextField(txtZoekSleutel = new JTextField(), "", 170, 10, 300, heightField, pQueryInput);
        txtZoekSleutel.addKeyListener(new KeyAdapter() {

            @Override
            public void keyReleased(KeyEvent e) {
                searchReis();
            }
        
        });
        
        butZoeken = UIHelper.createButton(butZoeken = new JButton(), "Zoeken", 480, 10, 100, heightField, pQueryInput);
        butZoeken.addActionListener(
                new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        searchReis();
                    }
                });

        // Center sectie, database record detail
        pRecord = new JPanel();
        pRecord.setLayout(null);
        pRecord.setPreferredSize(new Dimension(400, 500));
        pRecord.setBorder(BorderFactory.createLineBorder(Color.blue));
        
        lblId = UIHelper.createLabel(lblId = new JLabel(), "Nummer", 20, 10, 150, heightField, pRecord);
        txtId = UIHelper.createTextField(txtId = new JTextField(), "", 170, 10, 100, heightField, pRecord);

        lblNaam = UIHelper.createLabel(lblNaam = new JLabel(), "Naam", 20, 40, 150, heightField, pRecord);
        txtNaam = UIHelper.createTextField(txtNaam = new JTextField(), "", 170, 40, 300, heightField, pRecord);

        lblLand = UIHelper.createLabel(lblLand = new JLabel(), "Land", 20, 70, 150, heightField, pRecord);
        cmbLand = UIHelper.createCombo(cmbLand = new JComboBox<Object>(), 170, 70, 300, heightField, pRecord);

        lblReistype = UIHelper.createLabel(lblReistype = new JLabel(), "Reistype", 20, 100, 150, heightField, pRecord);
        cmbReistype = UIHelper.createCombo(cmbReistype = new JComboBox<Object>(), 170, 100, 300, heightField, pRecord);

        lblDuur = UIHelper.createLabel(lblDuur = new JLabel(), "Reisduur", 20, 130, 150, heightField, pRecord);
        spinDuur = UIHelper.createSpinField(spinDuur = new JSpinField(), 0, 170, 130, 150, heightField, pRecord, SwingConstants.LEFT);

        lblVerlenging = UIHelper.createLabel(lblVerlenging = new JLabel(), "Verlening mogelijk", 20, 160, 150, heightField, pRecord);
        chkVerlenging = UIHelper.createCheckBox(chkVerlenging = new JCheckBox(),"", 170, 160, 150, heightField, pRecord);

        lblAfbeelding = UIHelper.createLabel(lblAfbeelding = new JLabel(), "Bestandsnaam foto", 20, 190, 150, heightField, pRecord);
        txtAfbeelding = UIHelper.createTextField(txtAfbeelding = new JTextField(), "", 170, 190, 300, heightField, pRecord);

        lblOmschrijving = UIHelper.createLabel(lblOmschrijving = new JLabel(), "Omschrijving", 20, 220, 150, heightField, pRecord);
        txtOmschrijving = new JEditorPane();
        txtOmschrijving.setEditorKit(new HTMLEditorKit());
        txtOmschrijvingScrollable = new JScrollPane(txtOmschrijving);
        txtOmschrijvingScrollable.setBounds(170, 220, 700, 100);
        pRecord.add(txtOmschrijvingScrollable);
        
        // foto
        picLabel = UIHelper.createLabel(picLabel= new JLabel(), "Geen foto beschikbaar", 550, 10, 320, 205, pRecord);
        picLabel.setBorder(BorderFactory.createLineBorder(Color.black, 2));

        // fill combobox with table data
        fillComboLand();
        fillComboReistype();
        
        butSave = UIHelper.createButton(butSave = new JButton(), "Opslaan", 170, 330, 120, heightField, pRecord);
        butSave.addActionListener(
                new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        System.out.println("save");
                        if(reisObj!=null) {
                            updateRecord(reisObj);
                        } else {
                            addRecord();
                        }
                    }
                });

        butDelete = UIHelper.createButton(butDelete = new JButton(), "Verwijderen", 310, 330, 120, heightField, pRecord);
        butDelete.addActionListener(
                new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        System.out.println("delete");
                        if(reisObj!=null) {
                            deleteRecord(reisObj);
                        }
                }});

        butEmpty = UIHelper.createButton(butDelete = new JButton(), "Leeg/Nieuw", 350, 10, 120, heightField, pRecord);
        butEmpty.addActionListener(
                new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        emptyAll();
                }});

        // refresh combobox Reistypes
        butRefresh = UIHelper.createButton(butRefresh = new JButton(), "", 480, 100, 30, heightField, pRecord);
        butRefresh.setIcon(new ImageIcon("src/nl/hanze/shoestring/ui/graphics/refresh.png"));
        butRefresh.addActionListener(
                new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        fillComboReistype();
                }});
        
        
        pRecord.add(butSave);
        pRecord.add(butDelete);

        pRecord.add(butEmpty);
        
        // fill tab pane
        add(pRecord, BorderLayout.CENTER);
        add(pQueryInput, BorderLayout.NORTH);
        addTable();
        emptyAll();
    }

    /**
     * Haal informatie uit database en toon in JTable
     */
    private void addTable() {

        // Gridcontainer
        pDbGrid = new JPanel(new BorderLayout(2, 3));

        // scroll pane eigenschappen
        scrollPaneRes = new JScrollPane(table);
        Dimension d = table.getPreferredSize();
        scrollPaneRes.setPreferredSize(new Dimension(d.width, table.getRowHeight() * numberOfRows));

        // navigatie container
        UIHelper.addNavigation(pNavigation = new JPanel(), table, scrollPaneRes, numberOfRows);
        
        // kolom eigenschappen - breedte
        Object[] headers = {"Nummer", "Naam", "Land", "Reistype", "Duur", "Verlengen", "Afbeelding", "Omschrijving"};
        int[] breedte = {50, 300, 100, 100, 100, 60, 100, 200};
        
        // tablemodel en eigenschappen instellen, kolombreedte etc
        model = new DefaultTableModel(headers, 0) {

            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
            
            // rendering van cellen, toont checkbox en juiste datum indien datatype overeenkomstig is
            // null velden veroorzaken fout, standaard maar op String gezet....
            @Override
            public Class getColumnClass(int column){
                try {
                 return getValueAt(0, column).getClass();
                } catch (java.lang.NullPointerException e) {
                    return String.class;
                }
            }

        };

        table.setModel(model);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        for (int i0 = 0; i0 < breedte.length; i0++) {
            table.getColumnModel().getColumn(i0).setPreferredWidth(breedte[i0]);
        }
        
        updateTable(true);

        // selecteer row door muisklik    
        table.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                reisObj = reisList.get(table.convertRowIndexToModel(table.getSelectedRow()));
                getRecord(reisObj);
            }
        });

        pDbGrid.add(scrollPaneRes, BorderLayout.CENTER);
        pDbGrid.add(pNavigation, BorderLayout.SOUTH);
        add(pDbGrid, BorderLayout.SOUTH);
    }
    
    private void fillComboLand() {
        List<Land> land = logic.getLandList();
        Collections.sort(land);
        cmbLand.setModel(new DefaultComboBoxModel(land.toArray()));
    }
    
    private void fillComboReistype() {
        List<Reistype> reistype = logic.getReistypeList();
        cmbReistype.setModel(new DefaultComboBoxModel(reistype.toArray()));
    }
    
    
    /*
     *  Vul detailvelden met geselecteerde rowdata  
     */
    private void getRecord(Reis reisObj) {
        txtId.setText("" + reisObj.getId());
        txtId.setEditable(false);
        txtNaam.setText("" + reisObj.getNaam());
        cmbLand.setSelectedItem(reisObj.getLandId());
        cmbReistype.setSelectedItem(reisObj.getReistypeId());
        spinDuur.setValue(reisObj.getDuur());
        chkVerlenging.setSelected(reisObj.getVerlenging());
        txtAfbeelding.setText(reisObj.getAfbeelding());
        txtOmschrijving.setText(reisObj.getOmschrijving());     
        toonImage(txtAfbeelding.getText());
    }  
    
    /*
     * Toon foto als plaatje
     */
    private void toonImage(String file) {
        try {
            //BufferedImage myPicture = ImageIO.read(new File("M:\\Dropbox\\Shoestring JPA\\sql scripts\\foto\\" + file));
            BufferedImage myPicture = ImageIO.read(new File("C:\\Shoestring\\foto\\" + file));
            picLabel.setIcon(new ImageIcon( myPicture ));
        } catch (IOException ex) {
            try {
                BufferedImage myPicture = ImageIO.read(new File("src/nl/hanze/shoestring/ui/graphics/no_picture.png"));
                picLabel.setIcon(new ImageIcon( myPicture ));
            } catch (IOException ex1) {}
          }
    }
    
    /*
     *  update record  
     */
    private void updateRecord(Reis reisObj) {
        reisObj.setNaam(txtNaam.getText());
        reisObj.setLandId((Land) cmbLand.getModel().getSelectedItem());
        reisObj.setReistypeId((Reistype) cmbReistype.getModel().getSelectedItem());
        reisObj.setDuur(spinDuur.getValue());
        reisObj.setVerlenging(chkVerlenging.isSelected()==true);
        reisObj.setAfbeelding(txtAfbeelding.getText());
        reisObj.setOmschrijving(Utils.removeExtraTags(txtOmschrijving.getText()));
        logic.updateReis(reisObj);
        updateTable(true);
        emptyAll();
    }
    
    /*
     *  add new record  
     */
    private void addRecord() {
        reisObj = new Reis();
        reisObj.setNaam(txtNaam.getText());
        reisObj.setLandId((Land) cmbLand.getModel().getSelectedItem());
        reisObj.setReistypeId((Reistype) cmbReistype.getModel().getSelectedItem());
        reisObj.setDuur(spinDuur.getValue());
        reisObj.setVerlenging(chkVerlenging.isSelected()==true);
        reisObj.setAfbeelding(txtAfbeelding.getText());
        reisObj.setOmschrijving(Utils.removeExtraTags(txtOmschrijving.getText()));
        logic.addReis(reisObj);
        updateTable(true);        
        emptyAll();
    }

    /*
     *  delete record  
     */
    private void deleteRecord(Reis reisObj) {
        logic.deleteReis(reisObj);
        updateTable(true);
        emptyAll();
    }
    
    /*
     *  maak velden leeg en reistypeObj =null  
     */
    private void emptyAll() {
        txtId.setEditable(false);
        txtId.setText("");
        txtId.setEditable(false);
        txtNaam.setText("");
        cmbLand.setSelectedItem(null);
        cmbReistype.setSelectedItem(null);
        spinDuur.setValue(0);
        chkVerlenging.setSelected(false);
        txtAfbeelding.setText("");
        txtOmschrijving.setText("");
        toonImage("");
        reisObj=null;
    }

    private void updateTable(Boolean refresh) {
        if(refresh) {
            reisList = logic.getReisList();
        }

        model.setRowCount(0);
        // data in JTable plaatsen
        for (Reis Reis : reisList) {
            Object[] o = {Reis.getId(),
                Reis.getNaam(),
                Reis.getLandId().getNaam(),
                Reis.getReistypeId().getNaam(),
                Reis.getDuur(),
                Reis.getVerlenging(),
                Reis.getAfbeelding(),
                Reis.getOmschrijving()};
            model.addRow(o);
        }
    }
    
    public void searchReis(){
        reisList = logic.searchReis(txtZoekSleutel.getText());
        updateTable(false);
    }
}

